package com.it.service.impl;

import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.it.context.BaseContext;
import com.it.exception.BaseException;
import com.it.mapper.KnowledgeMapper;
import com.it.pojo.dto.KnowledgeAddDTO;
import com.it.pojo.dto.KnowledgeListDTO;
import com.it.pojo.entity.Knowledge;
import com.it.pojo.entity.KnowledgeFile;
import com.it.pojo.vo.KnowledgeVO;
import com.it.pojo.vo.KnowledgeFileVO;
import com.it.pojo.entity.PageResult;
import com.it.service.KnowledgeService;
import com.it.utils.AliOssUtil;
import com.it.utils.RagFileUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.time.LocalDateTime;
import java.util.Arrays;
import java.util.List;
import java.util.UUID;

@Service
@Slf4j
public class KnowledgeServiceImpl implements KnowledgeService {

    @Autowired
    private KnowledgeMapper knowledgeMapper;

    @Autowired
    private AliOssUtil aliOssUtil;
    
    @Autowired
    private RagFileUtil ragFileUtil;

    /**
     * 获取知识库列表（分页查询）
     *
     * @param knowledgeListDTO 查询参数
     * @return 分页结果
     */
    @Override
    public PageResult pageQuery(KnowledgeListDTO knowledgeListDTO) {
        // 设置默认分页参数
        if (knowledgeListDTO.getPage() == null || knowledgeListDTO.getPage() <= 0) {
            knowledgeListDTO.setPage(1);
        }
        if (knowledgeListDTO.getPageSize() == null || knowledgeListDTO.getPageSize() <= 0) {
            knowledgeListDTO.setPageSize(10);
        }

        // 开始分页
        PageHelper.startPage(knowledgeListDTO.getPage(), knowledgeListDTO.getPageSize());

        // 使用简化版查询，避免N+1问题
        Page<KnowledgeVO> page = knowledgeMapper.pageQuerySimple(knowledgeListDTO);

        // 构建分页结果
        return new PageResult(page.getTotal(), page.getResult());
    }

    /**
     * 添加知识库
     *
     * @param knowledgeAddDTO 添加参数
     */
    @Override
    public void add(KnowledgeAddDTO knowledgeAddDTO) {
        Knowledge knowledge = new Knowledge();
        BeanUtils.copyProperties(knowledgeAddDTO, knowledge);

        // 设置用户ID
        Long currentUserId = BaseContext.getCurrentId();
        log.info("当前用户ID: {}", currentUserId);

        knowledge.setUserId(currentUserId);

        // 生成知识库编码（基于时间戳）
        String tempKnowledgeCode = "KB" + System.currentTimeMillis();
        knowledge.setKnowledgeCode(tempKnowledgeCode);

        // 设置默认状态和文件数量
        knowledge.setStatus(1);
        knowledge.setFileCount(0);

        // 动态插入知识库
        knowledgeMapper.insertKnowledge(knowledge);
    }

    /**
     * 根据知识库编码删除知识库
     *
     * @param knowledgeCode 知识库编码
     */
    @Override
    public void deleteByKnowledgeCode(String knowledgeCode) {
        // 1, 判断是否存在该知识库
        Knowledge knowledge = knowledgeMapper.selectByKnowledgeCode(knowledgeCode);
        if (knowledge == null) {
            throw new BaseException("知识库不存在");
        }
        // 2, 删除
        knowledgeMapper.deleteByKnowledgeCode(knowledgeCode);
    }

    /**
     * 文件上传
     *
     * @param uploadFile 上传的文件
     * @return 文件访问URL
     */
    @Override
    @Transactional
    public String upload(MultipartFile uploadFile, String knowledgeCode) {
        try {
            // 获取原始文件名
            String originalFileName = uploadFile.getOriginalFilename();
            log.info("开始上传文件: {}", originalFileName);

//            // 生成唯一的文件名，避免文件名冲突 -- 使用oss的上传方式
            String extension = "";
            if (originalFileName != null) {
                int lastDotIndex = originalFileName.lastIndexOf('.');
                if (lastDotIndex > 0) {
                    extension = originalFileName.substring(lastDotIndex);
                }
            }
//            String uniqueFileName = UUID.randomUUID().toString() + extension;
            // 判断文件名是否重复
            KnowledgeFile file = knowledgeMapper.selectFileByFileNameAndUserId(originalFileName, BaseContext.getCurrentId());
            if (file != null) {
                log.info("文件已存在或文件名重复，请勿重复上传");
                return file.getFilePath();
            }
            String uniqueFileName = "(" + knowledgeCode + ")" + originalFileName;

            // 读取文件内容为字节数组
            byte[] fileBytes = uploadFile.getBytes();

            // 调用阿里云OSS工具类上传文件
//            String fileUrl = aliOssUtil.upload(fileBytes, uniqueFileName);
            // 调用ragFileUtil工具类上传文件到本地
            String fileUrl = ragFileUtil.uploadFile(fileBytes, uniqueFileName);

            log.info("文件上传成功，访问URL: {}", fileUrl);
            // 将url存储到数据库
            KnowledgeFile knowledgeFile = KnowledgeFile.builder().fileName(uniqueFileName)
                    .userId(BaseContext.getCurrentId())
                    .filePath(fileUrl)
                    .fileSize(fileBytes.length)
                    .status(1)
                    .knowledgeCode(knowledgeCode)
                    .fileType(extension.substring(1))
                    .createTime(LocalDateTime.now())
                    .updateTime(LocalDateTime.now())
                    .build();

            knowledgeMapper.addFile(knowledgeFile);
            // 更新文件数量
            updateFileCount(knowledgeCode);
            return fileUrl;

        } catch (IOException e) {
            log.error("文件上传失败，读取文件内容时发生错误: {}", e.getMessage(), e);
            throw new BaseException("文件上传失败：读取文件内容时发生错误");
        } catch (Exception e) {
            log.error("文件上传失败: {}", e.getMessage(), e);
            throw new BaseException("文件上传失败：" + e.getMessage());
        }
    }

    /**
     * 根据知识库编码获取文件列表
     *
     * @param knowledgeCode 知识库编码
     * @return 文件列表
     */
    @Override
    public List<KnowledgeFileVO> getKnowledgeFilesByCode(String knowledgeCode) {
        log.info("开始查询知识库文件列表，知识库编码: {}", knowledgeCode);
        
        // 调用Mapper查询文件列表
        List<KnowledgeFileVO> fileList = knowledgeMapper.selectFilesByKnowledgeCode(knowledgeCode);
        
        log.info("查询到文件数量: {}", fileList != null ? fileList.size() : 0);
        return fileList;
    }

    /**
     * 获取文件内容
     *
     * @param fileName 文件名
     * @return 文件内容
     */
    @Override
    public String getFileContent(String fileName) {
        log.info("开始获取文件内容，文件名: {}", fileName);
        // 查查文件路径
        KnowledgeFile knowledgeFile = knowledgeMapper.selectFileByFileName(fileName);
        try {
            String fileInfo = ragFileUtil.getFileByPath(knowledgeFile.getFilePath());

            return fileInfo;
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 删除文件
     *
     * @param fileId 文件ID
     */
    @Override
    @Transactional
    public void deleteFileById(Integer fileId) {
        // 查询文件所在的知识库编码
        KnowledgeFile knowledgeFile = knowledgeMapper.selectKnowledgeByFileCode(fileId);

        // 删除真实存储的文件
        ragFileUtil.deleteFile(knowledgeFile.getFilePath());

        // 删除文件
        knowledgeMapper.deleteKnowledgeFileById(fileId);

        // 修改文件数量
        knowledgeMapper.updateFileCount(knowledgeFile.getKnowledgeCode());
    }

    /**
     * 更新文件数量
     *
     * @param knowledgeCode 知识库编码
     */
    private void updateFileCount(String knowledgeCode) {
        knowledgeMapper.updateFileCount(knowledgeCode);
    }
}
